package indi.mozping.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * @author by mozping
 * @Classname MongodbUtil
 * @Description TODO
 * @Date 2019/2/22 16:26
 */
public class MongodbUtil {

    private static final Logger LOG = LoggerFactory.getLogger(MongodbUtil.class);

    public static JSONArray documentIterableToJsonArray(FindIterable<Document> res) {

        JSONArray jsonArray = new JSONArray();
        if (res == null) {
            return jsonArray;
        }

        Document doc;
        for (Document re : res) {
            doc = re;
            JSONObject jsonObject = new JSONObject();
            for (Map.Entry entry : doc.entrySet()) {
                String key = entry.getKey().toString();
                if (StrUtil.isTimeKey(key)) {
                    try {
                        String strDate = DateUtil.getFormarMonth((Date) doc.get(key), GlobalConsts.DEFAULT_TIME_PATTERN);
                        jsonObject.put(key, strDate);
                    } catch (Exception e) {
                        jsonObject.put(key, doc.get(key));
                        //LOG.error("转换异常", e);
                    }
                } else if ("_id".equalsIgnoreCase(key)) {
                    jsonObject.put(key, doc.getObjectId("_id").toString());
                } else {
                    jsonObject.put(key, doc.get(key));
                }
                //jsonObject.put(entry.getKey().toString(), entry.getValue());
            }
            jsonArray.add(jsonObject);
        }

        return jsonArray;

    }


    public static BasicDBObject combineCondition(String connector, BasicDBObject... basicDBObject) {

        String conditionConnector = connector;
        BasicDBList totalList = new BasicDBList();
        BasicDBObject allCondition = new BasicDBObject();
        if (StrUtil.isBlank(conditionConnector) || conditionConnector.equalsIgnoreCase(GlobalConsts.AND)) {
            conditionConnector = GlobalConsts.CONDITION_AND;
        } else {
            conditionConnector = GlobalConsts.CONDITION_OR;
        }

        for (BasicDBObject aBasicDBObject : basicDBObject) {
            if (aBasicDBObject != null && !aBasicDBObject.isEmpty()) {
                LOG.debug("连接查询条件" + aBasicDBObject.toString());
                totalList.add(aBasicDBObject);
            }
        }
        if (!totalList.isEmpty()) {
            allCondition.append(conditionConnector, totalList);
            LOG.info("处理后的查询条件" + allCondition.toString());
        }
        return allCondition;
    }

    public static BasicDBObject dealInCondition(JSONObject in) {
        BasicDBObject inCond = new BasicDBObject();
        if (in != null && !in.isEmpty()) {
            LOG.info("处理in查询条件...");
            for (String key : in.keySet()) {
                //获取json里面的条件
                ArrayList<String> arr = StrUtil.getRetKeys(in.getString(key));
                BasicDBList values = StrUtil.getInBasicDBList(key, arr);
                inCond.put(key, new BasicDBObject("$in", values));
            }
            LOG.info("in 条件为: " + inCond.toString());
        }
        return inCond;
    }


    /**
     * 处理equal模糊条件的方法
     *
     * @param eqCondition equal条件
     * @return com.mongodb.BasicDBObject equal条件
     */
    public static BasicDBObject dealEqCondition(JSONArray eqCondition) {

        BasicDBObject eqCond = new BasicDBObject();
        if (eqCondition != null && !eqCondition.isEmpty()) {
            BasicDBList eqConditionList = new BasicDBList();

            for (int i = 0; i < eqCondition.size(); i++) {
                BasicDBObject basicDBObject = new BasicDBObject();
                JSONObject jsonObj = eqCondition.getJSONObject(i);
                for (Map.Entry entry : jsonObj.entrySet()) {
                    if ("_id".equalsIgnoreCase(entry.getKey().toString())) {
                        //处理_id的查询条件
                        basicDBObject.append(entry.getKey().toString(), new ObjectId(entry.getValue().toString()));
                    } else {
                        basicDBObject.append(entry.getKey().toString(), entry.getValue());
                    }
                }
                eqConditionList.add(basicDBObject);
            }
            eqCond.append("$and", eqConditionList);
        }
        return eqCond;
    }

    public static BasicDBObject dealWhereCondition(JSONObject whereCondition) throws ParseException {

        BasicDBObject whereCond = new BasicDBObject();
        if (whereCondition != null && !whereCondition.isEmpty()) {
            LOG.info("处理过滤查询条件...");
            BasicDBList whereConditionList = new BasicDBList();

            JSONArray arr;

            Set<String> ks;
            Date date;
            // 取出所有要过滤的字段
            for (String st : whereCondition.keySet()) {
                BasicDBObject query = new BasicDBObject();
                BasicDBObject details = new BasicDBObject();
                // 处理单个过滤字段条件
                arr = whereCondition.getJSONArray(st);
                for (int j = 0; j < arr.size(); j++) {
                    JSONObject filter = arr.getJSONObject(j);
                    ks = filter.keySet();
                    for (String sign : ks) {
                        if (StrUtil.isTimeKey(st)) {
                            try {
                                date = DateUtil.convertStringToDate(GlobalConsts.DEFAULT_TIME_PATTERN, filter.getString(sign));
                                details.append(sign, date);
                            } catch (ParseException e) {
                                details.append(sign, filter.get(sign));
                                throw e;
                            }

                        } else {
                            details.append(sign, filter.get(sign));
                        }
                    }
                }
                query.put(st, details);
                whereConditionList.add(query);
            }
            whereCond.append("$and", whereConditionList);
        }
        return whereCond;
    }

    public static BasicDBObject dealLikeCondition(JSONArray like) {
        if (like == null || like.isEmpty()) {
            return new BasicDBObject();
        }
        Pattern pattern = null;
        String reg;
        String key = null;
        JSONObject likeJson = like.getJSONObject(0);
        for (Map.Entry entry : likeJson.entrySet()) {
            reg = entry.getValue().toString();
            key = entry.getKey().toString();
            pattern = Pattern.compile(reg);
        }

        BasicDBObject regex = new BasicDBObject();
        regex.put("$regex", pattern);
        BasicDBObject query = new BasicDBObject(key, regex);
        return query;
    }

    public static BasicDBObject dealSortCondition(JSONObject orderBy) {
        // 排序处理
        BasicDBObject sortCond = new BasicDBObject();
        JSONObject json = new JSONObject();

        if (orderBy != null && !orderBy.isEmpty()) {
            for (Map.Entry entry : orderBy.entrySet()) {
                if (!"mode".equals(entry.getKey().toString())) {
                    json.put(entry.getKey().toString(), entry.getValue());
                }
            }
            sortCond = (BasicDBObject) com.mongodb.util.JSON.parse(json.toString());
        }
        return sortCond;

    }
}
